#ifndef JUEGOSERVERIMP_H_
#define JUEGOSERVERIMP_H_

#include <string>
#include <vector>
#include "Juego.h"
#include "Mensaje.h"
#include "Observable.h"
#include "EstadoDelJuego.h"
#include "TiradorDeDados.h"
#include "Server.h"

class FabricaDeJugadores;

using namespace std;

class JuegoServerImp : public Juego, public Observable
{
private:
	int tamanio;
	
	Server* server;
	TiradorDeDados* tiradorDeDados;
	FabricaDeJugadores* fabricaDeJugadores;
	EstadoDelJuego* estadoDeEsperaDeJugadores;
	EstadoDelJuego* estadoDePreparacionDePartida;
	EstadoDelJuego* estadoDeRealizacionDePartida;
	EstadoDelJuego* estadoDePartidaFinalizada;
	
	EstadoDelJuego* estadoDelJuego;
	
public:
	JuegoServerImp(unsigned int cantidadDeJugadores, Mapa* mapa, TiradorDeDados* tiradorDeDados, Server* server,
			FabricaDeJugadores* fabricaDeJugadores);
	
	/*@throws JugadorExistenteException en caso de que ya exista un jugador del color dado*/
	void unirse(Jugador* jugador);
	
	/**pre: El juego debe estar en el EstadoDeEsperaDeJugadores.
	 * pre: Debe haber por lo menos 2 jugadores unidos al juego.
	 * LLeva al Juego desde el EstadoDeEsperaDeJugadores, al EstadoDePreparacionDePartida.
	 * @param jugadorAcargo Jugador* el jugador que primero se unio al juego.
	 * @throws InvalidStateException si se llama en un estado del juego que no sea EstadoDeEsperaDeJugadores.
	 * @throws NotEnoughPlayersException si se llama cuando hay un solo jugador unido al juego.
	 * @throws PlayerIsNotOwnerException si se llama por un jugador que no es el dueño del juego.
	 */ 
	void iniciar(Jugador* jugadorAcargo);
	void realizarAtaque(Ataque* ataque);
	void colocarEjercitos(Jugador* jugador, Territorio* territorio, unsigned int cantidadDeEjercitos);
	void moverEjercitos(Jugador* jugador, Territorio* origen, Territorio* destino, unsigned int cantidadDeEjercitos);
	void tirarDados(Jugador* jugador, unsigned int cantidadDeDados);
	void pasar(Jugador* jugador);
	
	/**En jugador envia un mensaje a sus contrincantes**/
	void hablar(string nombreJugador, string mensaje);
	
	EstadoDelJuego* getEstadoDeEsperaJugadores();
	EstadoDelJuego* getEstadoDePreparacionDePartida();
	EstadoDelJuego* getEstadoDeRealizacionDePartida();
	EstadoDelJuego* getEstadoDePartidaFinalizada();
	void setEstado(EstadoDelJuego* estado);
	EstadoDelJuego* getEstado();
	
	Server* getServer();
	FabricaDeJugadores* getFabricaDeJugadores();
	TiradorDeDados* getTiradorDeDados();
	void setTurno(int turno);
	void pasarAlSiguienteTurno();
	void imprimirEstado();
	
	void abandonar(Jugador* jugador);
	void finalizar();
	virtual ~JuegoServerImp();
};

#endif /*JUEGOSERVERIMP_H_*/
